<?php
namespace App\Api\Controllers\Weixin;


use App\Api\Controllers\Push\JpushController;
use App\Common\MerchantFuwu;
use App\Common\PaySuccessAction;
use App\Common\StoreDayMonthOrder;
use App\Common\UserGetMoney;
use App\Jobs\WXProfitSharing;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Store;
use App\Models\WeixinaStore;
use App\Models\WeixinStore;
use EasyWeChat\Factory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use App\Api\Controllers\Weixin\PayController;

class NotifyController extends BaseController
{

    //支付
    public function qr_pay_notify(Request $request)
    {
        try {
            $data = $request->getContent();
            $array_data = json_decode(json_encode(simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            $attach = $array_data['attach'];
            $attach_array = explode(",", $attach);
            $store_id = $attach_array[0];
            $config_id = $attach_array[1];
            $options = $this->Options($config_id);
            $config = [
                'app_id' => $options['app_id'],
                'mch_id' => $options['payment']['merchant_id'],
                'key' => $options['payment']['key'],
                'cert_path' => $options['payment']['cert_path'], // XXX: 绝对路径！！！！
                'key_path' => $options['payment']['key_path'],     // XXX: 绝对路径！！！！
            ];
            $app = Factory::payment($config);
            $response = $app->handlePaidNotify(function ($message, $fail) {
                file_put_contents('n.log',var_export($message,true)."\r\n",FILE_APPEND);
//                Log::info('微信官方-支付回调-message');
//                Log::info($message);
                $out_trade_no = $message['out_trade_no'];

                $day = date('Ymd', time());
                $table = 'orders_' . $day;
                if (Schema::hasTable($table)) {
                    $order = DB::table($table)->where('out_trade_no', $out_trade_no)->first();
                } else {
                    $order = Order::where('out_trade_no', $out_trade_no)->first();
                }


                $merchant_id = $order->merchant_id;
                $store_id = $order->store_id;
                $config_id = $order->config_id;
                //订单和库里的状态不一致
                if ($message['return_code'] != $order->status) {
                    ///////////// <- 建议在这里调用微信的【订单查询】接口查一下该笔订单的情况，确认是已经支付 /////////////
                    if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                        // 用户是否支付成功
                        if (array_get($message, 'result_code') === 'SUCCESS') {
                            $data_in = [
                                'receipt_amount' => 0,//商家实际收到的款项
                                'status' => $message['result_code'],
                                'pay_status' => 1,//系统状态
                                'pay_status_desc' => '支付成功',
                                'payment_method' => $message['bank_type'],
                                'buyer_id' => $message['openid'],
                                'trade_no' => $message['transaction_id'],
                            ];
                            $this->update_day_order($data_in,$out_trade_no);

                            $type = 2002;//静态码公众号支付

                            //动太码
                            if ($message['trade_type'] == "NATIVE") {
                                $type = 2003;
                            }

                            if (strpos($out_trade_no, 'scan')) {

                            }else{
                                $data = [
                                    'ways_type' => $order->ways_type,
                                    'ways_type_desc' => $order->ways_type_desc,
                                    'company' => $order->company,
                                    'source_type' => '2000',//返佣来源
                                    'source_desc' => '微信支付',//返佣来源说明
                                    'total_amount' => $order->total_amount,
                                    'out_trade_no' => $order->out_trade_no,
                                    'other_no' => $order->other_no,
                                    'rate' => $order->rate,
                                    'fee_amount' => $order->fee_amount,
                                    'merchant_id' => $order->merchant_id,
                                    'store_id' => $order->store_id,
                                    'user_id' => $order->user_id,
                                    'config_id' => $config_id,
                                    'store_name' => $order->store_name,
                                    'remark' => $order->remark,
                                    'ways_source' => $order->ways_source,
                                    'device_id' => $order->device_id,
                                ];
                                PaySuccessAction::action($data);
                            }

                            //支付成功，请求单次分账
                            if ($order->ways_type == 2000) {
                                $wx_store_obj = WeixinStore::where('store_id', $store_id)->first();
                                if ($wx_store_obj) {
                                    $is_profit_sharing = $wx_store_obj->is_profit_sharing; //是否分账(0-不分;1-分)
                                    $wx_sharing_rate = $wx_store_obj->wx_sharing_rate; //分账比例
                                    if (isset($is_profit_sharing) && $is_profit_sharing) {
                                        if (isset($wx_sharing_rate) && ($wx_sharing_rate > 0)) {
                                            $wx_pay_obj = new PayController();
                                            $profit_sharing_add_receiver_data = [
                                                'user_id' => $order->user_id,
                                                'out_trade_no' => $out_trade_no,
                                                'store_id' => $store_id,
                                                'options' => $this->Options($config_id),
                                                'wx_sub_merchant_id' => $wx_store_obj->wx_sub_merchant_id, //微信支付分配的子商户号
                                                'transaction_id' => $message['transaction_id'], //微信支付订单号
                                                'total_amount' => $order->total_amount,
                                                'ways_type' => $order->ways_type
                                            ];

                                            //todo:调用支付成功之后，进行分账的队列

                                            Log::info('微信官方支付,请求单次分账');
                                            Log::info($profit_sharing_add_receiver_data);
                                            $reqResult = $wx_pay_obj->profit_sharing($profit_sharing_add_receiver_data);
                                            Log::info($reqResult);
                                        } else {
                                            Log::info('微信官方支付error, 订单号：'.$out_trade_no.'分账比例为: '.$wx_sharing_rate);
                                        }
                                    }
                                }
                            }

                            // 用户支付失败
                        } elseif (array_get($message, 'result_code') === 'FAIL') {

                        }

                    } else {
                        return $fail('通信失败，请稍后再通知我');
                    }
                }

                return true; // 返回处理完成
            });

            return $response;
        } catch (\Exception $ex) {
            Log::info('微信支付异步');
            Log::info($ex->getMessage().' | '.$ex->getLine());
        }
    }


    //微信官方a 支付回调
    public function qr_pay_notify_a(Request $request)
    {
        try {
            $data = $request->getContent();
            $array_data = json_decode(json_encode(simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
//            Log::info('微信官方a-支付回调');
//            Log::info($array_data);

            $attach = $array_data['attach'];
            $attach_array = explode(",", $attach);
            $store_id = $attach_array[0];
            $config_id = $attach_array[1];
            $options = $this->OptionsA($config_id);
            $config = [
                'app_id' => $options['app_id'],
                'mch_id' => $options['payment']['merchant_id'],
                'key' => $options['payment']['key'],
                'cert_path' => $options['payment']['cert_path'], // XXX: 绝对路径！！！！
                'key_path' => $options['payment']['key_path'],     // XXX: 绝对路径！！！！
            ];
            $app = Factory::payment($config);
            $response = $app->handlePaidNotify(function ($message, $fail) {
//                Log::info('微信官方a-message');
//                Log::info($message);
                $out_trade_no = $message['out_trade_no'];

                $day = date('Ymd', time());
                $table = 'orders_' . $day;
                if (Schema::hasTable($table)) {
                    $order = DB::table($table)->where('out_trade_no', $out_trade_no)->first();
                } else {
                    $order = Order::where('out_trade_no', $out_trade_no)->first();
                }

                $merchant_id = $order->merchant_id;
                $store_id = $order->store_id;
                $config_id = $order->config_id;
                //订单和库里的状态不一致
                if ($message['return_code'] != $order->status) {
                    ///////////// <- 建议在这里调用微信的【订单查询】接口查一下该笔订单的情况，确认是已经支付 /////////////
                    if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                        // 用户是否支付成功
                        if (array_get($message, 'result_code') === 'SUCCESS') {
                            $data_in = [
                                'receipt_amount' => 0, //商家实际收到的款项
                                'status' => $message['result_code'],
                                'pay_status' => 1, //系统状态
                                'pay_status_desc' => '支付成功',
                                'payment_method' => $message['bank_type'],
                                'buyer_id' => $message['openid'],
                                'trade_no' => $message['transaction_id'],
                            ];
                            $res = $this->update_day_order($data_in, $out_trade_no);
                            if (!$res) {
                                Log::info('微信支付a-支付回调-更新失败: '.$out_trade_no);
                            }

                            $type = 4002; //静态码公众号支付

                            //动态码
                            if ($message['trade_type'] == "NATIVE") {
                                $type = 4003;
                            }

                            if (strpos($out_trade_no, 'scan')) {

                            }else{
                                $data = [
                                    'ways_type' => $order->ways_type,
                                    'ways_type_desc' => $order->ways_type_desc,
                                    'company' => $order->company,
                                    'source_type' => '4000', //返佣来源
                                    'source_desc' => '微信支付a', //返佣来源说明
                                    'total_amount' => $order->total_amount,
                                    'out_trade_no' => $order->out_trade_no,
                                    'other_no' => $order->other_no,
                                    'rate' => $order->rate,
                                    'fee_amount' => $order->fee_amount,
                                    'merchant_id' => $order->merchant_id,
                                    'store_id' => $order->store_id,
                                    'user_id' => $order->user_id,
                                    'config_id' => $config_id,
                                    'store_name' => $order->store_name,
                                    'remark' => $order->remark,
                                    'ways_source' => $order->ways_source,
                                    'device_id' => $order->device_id,
                                ];
                                PaySuccessAction::action($data);
                            }

                            //支付成功，请求单次分账
                            if ($order->ways_type == 4000) {
                                $wx_store_obj = WeixinaStore::where('store_id', $store_id)->first();
                                if ($wx_store_obj) {
                                    $is_profit_sharing = $wx_store_obj->is_profit_sharing; //是否分账(0-不分;1-分)
                                    $wx_sharing_rate = $wx_store_obj->wx_sharing_rate; //分账比例
                                    if (isset($is_profit_sharing) && $is_profit_sharing) {
                                        if (isset($wx_sharing_rate) && ($wx_sharing_rate > 0)) {
                                            $wx_pay_obj = new PayController();
                                            $profit_sharing_add_receiver_data = [
                                                'user_id' => $order->user_id,
                                                'out_trade_no' => $out_trade_no,
                                                'store_id' => $store_id,
                                                'options' => $this->Options($config_id),
                                                'wx_sub_merchant_id' => $wx_store_obj->wx_sub_merchant_id, //微信支付分配的子商户号
                                                'transaction_id' => $message['transaction_id'], //微信支付订单号
                                                'total_amount' => $order->total_amount,
                                                'ways_type' => $order->ways_type,
                                            ];

                                            //todo:调用支付成功之后，进行分账的队列

                                            Log::info('微信官方a支付,请求单次分账');
                                            Log::info($profit_sharing_add_receiver_data);
                                            $reqResult = $wx_pay_obj->profit_sharing($profit_sharing_add_receiver_data);
                                            Log::info($reqResult);
                                        } else {
                                            Log::info('微信官方a支付error, 订单号：'.$out_trade_no.'分账比例为: '.$wx_sharing_rate);
                                        }
                                    }
                                }
                            }
                        } // 用户支付失败
                        elseif (array_get($message, 'result_code') === 'FAIL') {

                        }
                    }
                    else {
                        return $fail('通信失败，请稍后再通知我');
                    }
                }

                return true; // 返回处理完成
            });

            return $response;
        } catch (\Exception $ex) {
            Log::info('微信支付a异步error');
            Log::info($ex->getMessage().' | '.$ex->getLine());
        }
    }


    //学校支付
    public function school_pay_notify(Request $request)
    {
        try {
            $data = $request->getContent();
            $array_data = json_decode(json_encode(simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            $attach = $array_data['attach'];
            $attach_array = explode(",", $attach);
            $store_id = $attach_array[0];
            $config_id = $attach_array[1];
            $item_id = $attach_array[2];
            $item_array = explode("-", $item_id);
            $item_array = array_filter($item_array);//去除空值
            $item_array = array_values($item_array);//去除键值

            $options = $this->Options($config_id);
            $config = [
                'app_id' => $options['app_id'],
                'mch_id' => $options['payment']['merchant_id'],
                'key' => $options['payment']['key'],
                'cert_path' => $options['payment']['cert_path'], // XXX: 绝对路径！！！！
                'key_path' => $options['payment']['key_path'],     // XXX: 绝对路径！！！！
            ];
            $app = Factory::payment($config);
            $response = $app->handlePaidNotify(function ($message, $fail) {
                $out_trade_no = $message['out_trade_no'];
                $order = Order::where('out_trade_no', $out_trade_no)->first();
                $merchant_id = $order->merchant_id;
                //订单和库里的状态不一致
                if ($message['return_code'] != $order->status) {
                    ///////////// <- 建议在这里调用微信的【订单查询】接口查一下该笔订单的情况，确认是已经支付 /////////////
                    if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                        // 用户是否支付成功
                        if (array_get($message, 'result_code') === 'SUCCESS') {
                            $data_in = [
                                'receipt_amount' => $order->total_amount,//商家实际收到的款项
                                'status' => $message['result_code'],
                                'pay_status' => 1,//系统状态
                                'pay_status_desc' => '支付成功',
                                'payment_method' => $message['bank_type'],
                                'buyer_id' => $message['openid'],
                                'trade_no' => $message['transaction_id'],
                                'pay_time' => $message['time_end'],
                            ];
                            $order->update($data_in);
                            $order->save();
                            $type = 2005;//学校缴费

                            //写入学校状态

                            $attach = $message['attach'];
                            $attach_array = explode(",", $attach);
                            $store_id = $attach_array[0];
                            $config_id = $attach_array[1];
                            $item_id = $attach_array[2];
                            $item_array = explode("-", $item_id);
                            $item_array = array_filter($item_array);//去除空值
                            $item_array = array_values($item_array);//去除键值

                            $out_trade_no = $order->other_no;
                            $mul_item = $item_array;
                            $cin = [
                                'pay_amount' => $order->total_amount,//支付金额
                                'receipt_amount' => $order->total_amount,//商家在交易中实际收到的款项，单位为元
                                'buyer_id' => $message['openid'],//买家支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字,或者微信的openid
                                'buyer_logon_id' => $message['openid'],//买家支付宝账号，或者微信昵称
                                'pay_type' => '2005',//支付类型，1000-官方支付宝扫码，1005-支付宝行业缴费，2000-微信缴费，2005-微信支付缴费
                                'pay_type_desc' => '微信公众号缴费',//支付宝扫码，支付宝缴费，微信支付缴费  微信支付扫码
                                'pay_type_source' => 'weixin',//支付来源 如 alipay-支付宝，weixin-微信支付
                                'pay_type_source_desc' => '微信支付',//官方支付宝
                                'out_trade_no' => $out_trade_no,
                                'trade_no' => $message['transaction_id'],
                            ];
                            $re = \App\Logic\PrimarySchool\SyncOrder::paySuccess($out_trade_no, $mul_item, $cin);

                            //支付成功后的动作
                            $data = [
                                'ways_type' => $order->ways_type,
                                'ways_type_desc' => $order->ways_type_desc,
                                'source_type' => '2000',//返佣来源
                                'source_desc' => '微信支付',//返佣来源说明
                                'total_amount' => $order->total_amount,
                                'out_trade_no' => $order->out_trade_no,
                                'rate' => $order->rate,
                                'fee_amount' => $order->fee_amount,
                                'merchant_id' => $order->merchant_id,
                                'store_id' => $order->store_id,
                                'user_id' => $order->user_id,
                                'config_id' => $config_id,
                                'store_name' => $order->store_name,

                            ];


                            //  PaySuccessAction::action($data);


                            // 用户支付失败
                        } elseif (array_get($message, 'result_code') === 'FAIL') {


                        }

                    } else {
                        return $fail('通信失败，请稍后再通知我');
                    }
                }

                return true; // 返回处理完成
            });

            return $response;
        } catch (\Exception $ex) {
            Log::info('微信教育缴费异步error');
            Log::info($ex->getMessage().' | '.$ex->getLine());
        }
    }
    
    public  function mini_notify (Request $request)
    {
        try {
            $resource = $request->getContent();
            error_log(date('Y-m-d H:i:s')." 【微信小程序回调报文】： ".json_encode($resource)."\n\n", 3, "/tmp/". 'wx_mini'.date('Ymd').".log");

            $resource = $resource['resource'];
            $nonceStr = $resource['nonce'];
            $associatedData = $resource['associated_data'];
            $ciphertext = $resource['ciphertext'];
            $ciphertext = \base64_decode($ciphertext);
            if (strlen($ciphertext) <= 12) {
                error_log(date('Y-m-d H:i:s')." 【微信小程序回调报文】： ".json_encode(['微信支付回调返回数据有误'])."\n\n", 3, "/tmp/". 'wx_mini'.date('Ymd').".log");
            }
            if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) {
                //$APIv3_KEY就是在商户平台后端设置是APIv3秘钥
                $orderData = \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'zgjindoufuzgjindoufuzgjindoufuzg');
                $orderData = json_decode($orderData, true);

                error_log(date('Y-m-d H:i:s')." 【微信小程序回调】： ".json_encode($orderData)."\n\n", 3, "/tmp/". 'wx_mini'.date('Ymd').".log");
                //到数据库查看订单状态是否已更新为"success"
                $order = Order::where('out_trade_no', $orderData['out_trade_no'])->first();

                if ($orderData['trade_state'] != $order->status) {
                    ///////////// <- 建议在这里调用微信的【订单查询】接口查一下该笔订单的情况，确认是已经支付 /////////////
                    if ($orderData['trade_state'] === 'SUCCESS') {// 用户是否支付成功
                        $data_in = [
                            'receipt_amount' => 0,//商家实际收到的款项
                            'status' => $orderData['trade_state'],
                            'pay_status' => 1,//系统状态
                            'pay_status_desc' => '支付成功',
                            'payment_method' => $orderData['bank_type'],
                            'buyer_id' => $orderData['payer']['sub_openid'],
                            'trade_no' => $orderData['transaction_id'],
                        ];
                        $this->update_day_order($data_in, $orderData['out_trade_no']);


                        if (strpos($orderData['out_trade_no'], 'scan')) {

                        } else {
                            $data = [
                                'ways_type' => $order->ways_type,
                                'ways_type_desc' => $order->ways_type_desc,
                                'company' => $order->company,
                                'source_type' => '2000',//返佣来源
                                'source_desc' => '微信支付',//返佣来源说明
                                'total_amount' => $order->total_amount,
                                'out_trade_no' => $order->out_trade_no,
                                'other_no' => $order->other_no,
                                'rate' => $order->rate,
                                'fee_amount' => $order->fee_amount,
                                'merchant_id' => $order->merchant_id,
                                'store_id' => $order->store_id,
                                'user_id' => $order->user_id,
                                'config_id' => 1234,
                                'store_name' => $order->store_name,
                                'remark' => $order->remark,
                                'ways_source' => $order->ways_source,
                                'device_id' => $order->device_id,
                            ];
                            PaySuccessAction::action($data);
                        }
                        return ['code' => 'SUCCESS', 'message' => ''];
                    }
                }


            } else {
                error_log(date('Y-m-d H:i:s')." 【微信小程序回调】： ".json_encode(['AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php'])."\n\n", 3, "/tmp/". 'wx_mini'.date('Ymd').".log");
            }
        } catch (\Exception $ex) {
            error_log(date('Y-m-d H:i:s')." 【微信小程序回调】： ".json_encode([$ex->getMessage().' | '.$ex->getLine()])."\n\n", 3, "/tmp/". 'wx_mini'.date('Ymd').".log");
        }
    }


    public function goods_notify(Request $request)
    {
        try {
            $data = $request->getContent();
            $data = json_decode(json_encode(simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            error_log(date('Y-m-d H:i:s')." 【充值回调】： ".json_encode($data)."\n\n", 3, "/tmp/". 'wx_goods'.date('Ymd').".log");
//
//            $data = json_decode('{"appid":"wxd9d8c4e13a176553","bank_type":"OTHERS","cash_fee":"1","fee_type":"CNY","is_subscribe":"N","mch_id":"1509499221","nonce_str":"83d58083774d7649a4b25f84b1ce8fd8","openid":"oj3Yo4y_R_ZhNClnNj9WC5ck9pcg","out_trade_no":"wx17161905232166","result_code":"SUCCESS","return_code":"SUCCESS","sign":"3036E28BB7B16BA116DC534C25873CD5","time_end":"20240520153534","total_fee":"1","trade_type":"JSAPI","transaction_id":"4200002181202405209796445391"}', true);
            $sign = $data['sign'];
            unset($data['sign']);
            $newSign=$this->tosign($data);
            if ($newSign != $sign) {
                return false;
            }
            if (isset($data['return_code']) && $data['return_code'] == 'SUCCESS') {
                if (isset($data['result_code']) && $data['result_code'] == 'SUCCESS') {
                    $orderNo = $data['out_trade_no'];
                    $orderInfo = DB::table('goods_cost_log')->where('orderNo' , $orderNo)->first();
//                    var_dump($orderInfo->store_id);
                    if ($orderInfo->status == 1) {
                        DB::table('goods_cost_log')->where('orderNo' , $orderNo)->update(['status' => 2]);
                        $money =  number_format($data['total_fee'] * 0.01, 2, '.', '');
//                        var_dump($money);
                        DB::table('stores')->where('store_id' , $orderInfo->store_id)->increment('goods_cost_balance', $money);
                    }
                }
            }
        } catch (\Exception $ex) {
            error_log(date('Y-m-d H:i:s')." 【充值回调报错】： ".json_encode($ex->getMessage().' | '.$ex->getFile().' | '.$ex->getLine())."\n\n", 3, "/tmp/". 'wx_goods'.date('Ymd').".log");
        }
    }

    public function tosign($data){
        ksort($data);
        $string=$this->tourlparams($data);
        $string=$string.'&key=q85KjBjKu33b5dMU8kp25F4g2oqFKaoX';
        $string=strtoupper(md5($string));
        return $string;
    }

    public function tourlparams($params){
        $string='';
        if(!empty($params)){
            $array=array();
            foreach($params as $key=>$value){
                $array[]=$key.'='.$value;
            }
            $string=implode('&',$array);
        }
        return $string;
    }
}
